home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 1_2002.ISO / Data / Zips / TaskBar Co201085262001.psc / ctxTaskBar.ctl < prev    next >
Encoding:
Visual Basic user-defined control file  |  2001-05-27  |  30.8 KB  |  877 lines

  1. VERSION 5.00
  2. Begin VB.UserControl ctxTaskBar 
  3.    Alignable       =   -1  'True
  4.    BackColor       =   &H80000018&
  5.    CanGetFocus     =   0   'False
  6.    ClientHeight    =   2880
  7.    ClientLeft      =   0
  8.    ClientTop       =   0
  9.    ClientWidth     =   3840
  10.    DrawWidth       =   1768
  11.    ScaleHeight     =   2880
  12.    ScaleWidth      =   3840
  13.    Begin VB.Image imgDefIcon 
  14.       Height          =   192
  15.       Left            =   2940
  16.       Picture         =   "ctxTaskBar.ctx":0000
  17.       Top             =   420
  18.       Visible         =   0   'False
  19.       Width           =   192
  20.    End
  21.    Begin VB.Image imgCapture 
  22.       Height          =   1104
  23.       Left            =   1008
  24.       Top             =   1008
  25.       Width           =   1440
  26.    End
  27. End
  28. Attribute VB_Name = "ctxTaskBar"
  29. Attribute VB_GlobalNameSpace = False
  30. Attribute VB_Creatable = True
  31. Attribute VB_PredeclaredId = False
  32. Attribute VB_Exposed = True
  33. Option Explicit
  34.  
  35. Event StartMenu()
  36. Event BeforeTaskSwitch(ByVal NewTask As Long, Cancel As Boolean)
  37. Attribute BeforeTaskSwitch.VB_MemberFlags = "200"
  38. Event TrayMouseDown(ByVal Idx As Long, ByVal Button As Long, ByVal X As Long, ByVal Y As Long)
  39. Event TrayMouseUp(ByVal Idx As Long, ByVal Button As Long, ByVal X As Long, ByVal Y As Long)
  40. Event TaskMouseDown(ByVal Idx As Long, ByVal Button As Long, ByVal X As Long, ByVal Y As Long)
  41. Event TaskMouseUp(ByVal Idx As Long, ByVal Button As Long, ByVal X As Long, ByVal Y As Long)
  42.  
  43. '=========================================================================
  44. ' Constants and variables
  45. '=========================================================================
  46.  
  47. Private Const CONTROL_HEIGHT    As Long = 30
  48. Private Const SEP_WIDTH         As Long = 14
  49. Private Const BRD_WIDTH         As Long = 3
  50. Private Const MIN_BUTTON_WIDTH  As Long = 16 + 2 * BRD_WIDTH
  51. Private Const MAX_BUTTON_WIDTH  As Long = 165
  52. Private Const SNG_HIMETRIC      As Single = 21.66667
  53. Private Const TRAY_PADDING      As Long = 4
  54. Private Const DEF_STARTMENUCAPTION As String = "Start"
  55. Private Const DEF_STARTMENUTOOLTIPCAPTION As String = "Click here to begin"
  56. Private Const DEF_BUFFERDRAW    As Boolean = False
  57.  
  58. Private m_lActive           As Long
  59. Private m_lPressed          As Long
  60. Private m_oStartMenuIcon    As StdPicture
  61. Private m_sStartMenuCaption As String
  62. Private m_sStartMenuTooltipText As String
  63. Private m_bBufferDraw       As Boolean
  64.  
  65. Private m_cTasks            As cTaskBarInfos
  66. Private m_cTrayIcons        As cTaskBarInfos
  67. Private m_lControlLines     As Long
  68. Private m_lButtonWidth      As Long
  69. Private m_lButtonsPerLine   As Long
  70. Private m_bResizing         As Boolean
  71.  
  72. '=========================================================================
  73. ' Properties
  74. '=========================================================================
  75.  
  76. Property Get Font() As StdFont
  77.     Set Font = UserControl.Font
  78. End Property
  79.  
  80. Property Set Font(oValue As StdFont)
  81.     Set UserControl.Font = oValue
  82.     UserControl.Font.Bold = False
  83.     UserControl_Resize
  84.     PropertyChanged "Font"
  85. End Property
  86.  
  87. Property Get StartMenuIcon() As StdPicture
  88.     Set StartMenuIcon = m_oStartMenuIcon
  89. End Property
  90.  
  91. Property Set StartMenuIcon(oValue As StdPicture)
  92.     On Error Resume Next
  93.     Set m_oStartMenuIcon = oValue
  94.     Refresh
  95.     PropertyChanged "StartMenuIcon"
  96. End Property
  97.  
  98. Property Get StartMenuCaption() As String
  99. Attribute StartMenuCaption.VB_UserMemId = -518
  100.     StartMenuCaption = m_sStartMenuCaption
  101. End Property
  102.  
  103. Property Let StartMenuCaption(sValue As String)
  104.     m_sStartMenuCaption = sValue
  105.     Refresh
  106.     PropertyChanged "StartMenuCaption"
  107. End Property
  108.  
  109. Property Get StartMenuTooltipText() As String
  110.     StartMenuTooltipText = m_sStartMenuTooltipText
  111. End Property
  112.  
  113. Property Let StartMenuTooltipText(sValue As String)
  114.     m_sStartMenuTooltipText = sValue
  115.     PropertyChanged "StartMenuTooltipText"
  116. End Property
  117.  
  118. Property Get ActiveTask() As Long
  119. Attribute ActiveTask.VB_MemberFlags = "400"
  120.     ActiveTask = m_lActive
  121. End Property
  122.  
  123. Property Let ActiveTask(ByVal lValue As Long)
  124.     Dim rcClient As RECT
  125.     
  126.     On Error Resume Next
  127.     GetClientRect hWnd, rcClient
  128.     If m_lActive >= 0 Then
  129.         InvalidateRect hWnd, GetButtonRect(rcClient, m_lActive), 0
  130.     End If
  131.     If lValue >= 0 And lValue <= Tasks.Count Then
  132.         m_lActive = lValue
  133.     Else
  134.         m_lActive = -1
  135.     End If
  136.     If m_lActive >= 0 Then
  137.         InvalidateRect hWnd, GetButtonRect(rcClient, m_lActive), 0
  138.     End If
  139.     '--- fix redraw in IDE
  140.     Debug.Print DebugRefresh;
  141. End Property
  142.  
  143. Property Get PressedTask() As Long
  144.     PressedTask = m_lPressed
  145. End Property
  146.  
  147. Property Let PressedTask(ByVal lValue As Long)
  148.     Dim rcClient As RECT
  149.     
  150.     On Error Resume Next
  151.     GetClientRect hWnd, rcClient
  152.     If m_lPressed <> 0 Then
  153.         InvalidateRect hWnd, GetButtonRect(rcClient, Abs(m_lPressed)), 0
  154.     End If
  155.     If lValue >= -Tasks.Count And lValue <= Tasks.Count Then
  156.         m_lPressed = lValue
  157.     Else
  158.         m_lPressed = 0
  159.     End If
  160.     If m_lPressed <> 0 Then
  161.         InvalidateRect hWnd, GetButtonRect(rcClient, Abs(m_lPressed)), 0
  162.     End If
  163.     '--- fix redraw in IDE
  164.     Debug.Print DebugRefresh;
  165. End Property
  166.  
  167. Property Get BufferDraw() As Boolean
  168.     BufferDraw = m_bBufferDraw
  169. End Property
  170.  
  171. Property Let BufferDraw(ByVal bValue As Boolean)
  172.     m_bBufferDraw = bValue
  173.     PropertyChanged "BufferDraw"
  174. End Property
  175.  
  176. '= Collections ===========================================================
  177.  
  178. Property Get Tasks() As cTaskBarInfos
  179. Attribute Tasks.VB_MemberFlags = "400"
  180.     Set Tasks = m_cTasks
  181. End Property
  182.  
  183. Property Get TrayIcons() As cTaskBarInfos
  184. Attribute TrayIcons.VB_MemberFlags = "400"
  185.     Set TrayIcons = m_cTrayIcons
  186. End Property
  187.  
  188. '= Private ===============================================================
  189.  
  190. Private Property Get TrayWidth() As Long
  191.     Dim lTrayLines  As Long
  192.     On Error Resume Next
  193.     If m_lControlLines = 1 Then
  194.         TrayWidth = SEP_WIDTH + ClockWidth + TrayIcons.Count * (16 + TRAY_PADDING) + 2 * BRD_WIDTH + 2 + TRAY_PADDING
  195.     Else
  196.         lTrayLines = (GetControlHeight() - GetButtonHeight() - 2 * BRD_WIDTH) \ (16 + TRAY_PADDING)
  197.         TrayWidth = (16 + TRAY_PADDING) * ((TrayIcons.Count + lTrayLines - 1) \ lTrayLines)
  198.         If TrayWidth < ClockWidth Then
  199.             TrayWidth = ClockWidth
  200.         End If
  201.         TrayWidth = TrayWidth + SEP_WIDTH + 2 * BRD_WIDTH + 2 + TRAY_PADDING
  202.     End If
  203. End Property
  204.  
  205. Private Property Get StartMenuWidth() As Long
  206.     On Error Resume Next
  207.     UserControl.Font.Bold = True
  208.     StartMenuWidth = TextWidth(StartMenuCaption) / Screen.TwipsPerPixelX + 16 + 4 * BRD_WIDTH + 3
  209.     UserControl.Font.Bold = False
  210. End Property
  211.  
  212. Private Property Get ClockWidth() As Long
  213.     On Error Resume Next
  214.     ClockWidth = TextWidth(Format(Now, STR_SHORTTIME)) / Screen.TwipsPerPixelX + 6 * BRD_WIDTH
  215. End Property
  216.  
  217. Private Property Get DEF_STARTMENUICON() As StdPicture
  218.     Set DEF_STARTMENUICON = imgDefIcon.Picture
  219. End Property
  220.  
  221. Private Property Get DEF_FONT() As StdFont
  222.     Set DEF_FONT = New StdFont
  223.     DEF_FONT.Name = "Tahoma"
  224.     DEF_FONT.Size = 8
  225. End Property
  226.  
  227. '=========================================================================
  228. ' Methods
  229. '=========================================================================
  230.  
  231. Private Function DebugRefresh() As String
  232.     Refresh
  233. End Function
  234.  
  235. Private Function GetStartMenuRect(rcClient As RECT) As RECT
  236.     On Error Resume Next
  237.     GetStartMenuRect.Left = rcClient.Left
  238.     GetStartMenuRect.Top = rcClient.Top
  239.     GetStartMenuRect.Right = GetStartMenuRect.Left + StartMenuWidth + BRD_WIDTH
  240.     GetStartMenuRect.Bottom = GetStartMenuRect.Top + GetLineHeight() + BRD_WIDTH
  241.     InflateRect GetStartMenuRect, -BRD_WIDTH, -BRD_WIDTH
  242.     If GetStartMenuRect.Right > rcClient.Right - TrayWidth - SEP_WIDTH Then
  243.         GetStartMenuRect.Left = -1
  244.         GetStartMenuRect.Top = -1
  245.         GetStartMenuRect.Right = -1
  246.         GetStartMenuRect.Bottom = -1
  247.     End If
  248. End Function
  249.  
  250. Private Function GetButtonRect(rcClient As RECT, ByVal lIdx As Long) As RECT
  251.     Dim rcStart             As RECT
  252.     Dim lButtonLine         As Long
  253.     
  254.     On Error Resume Next
  255.     If lIdx = 0 Then
  256.         GetButtonRect = GetStartMenuRect(rcClient)
  257.     Else
  258.         lButtonLine = (lIdx - 1) \ m_lButtonsPerLine
  259.         GetButtonRect.Left = GetStartMenuRect(rcClient).Right + SEP_WIDTH + (lIdx - 1 - lButtonLine * m_lButtonsPerLine) * m_lButtonWidth - BRD_WIDTH
  260.         GetButtonRect.Top = rcClient.Top + lButtonLine * GetLineHeight()
  261.         GetButtonRect.Right = GetButtonRect.Left + m_lButtonWidth + BRD_WIDTH
  262.         GetButtonRect.Bottom = GetButtonRect.Top + GetLineHeight() + BRD_WIDTH
  263.         InflateRect GetButtonRect, -BRD_WIDTH, -BRD_WIDTH
  264.         If GetButtonRect.Right < GetButtonRect.Left + MIN_BUTTON_WIDTH Then
  265.             GetButtonRect.Left = -1
  266.             GetButtonRect.Top = -1
  267.             GetButtonRect.Right = -1
  268.             GetButtonRect.Bottom = -1
  269.         End If
  270.     End If
  271. End Function
  272.  
  273. Private Function GetTrayRect(rcClient As RECT) As RECT
  274.     On Error Resume Next
  275.     GetTrayRect.Left = rcClient.Right - TrayWidth + SEP_WIDTH
  276.     GetTrayRect.Top = rcClient.Top
  277.     GetTrayRect.Right = rcClient.Right
  278.     GetTrayRect.Bottom = rcClient.Bottom
  279.     InflateRect GetTrayRect, -BRD_WIDTH, -BRD_WIDTH
  280. End Function
  281.  
  282. Private Function GetClockRect(rcClient As RECT) As RECT
  283.     On Error Resume Next
  284.     GetClockRect = GetTrayRect(rcClient)
  285.     InflateRect GetClockRect, -1, -1
  286.     If m_lControlLines = 1 Then
  287.         GetClockRect.Left = GetClockRect.Right - ClockWidth
  288.     End If
  289.     GetClockRect.Bottom = GetClockRect.Top + GetButtonHeight() - 2
  290. End Function
  291.  
  292. Private Function GetTrayIconRect(rcClient As RECT, ByVal lIdx As Long) As RECT
  293.     Dim rcClock         As RECT
  294.     Dim rcTray          As RECT
  295.     Dim lIconsPerLine   As Long
  296.     Dim lIconRow        As Long
  297.     
  298.     On Error Resume Next
  299.     rcClock = GetClockRect(rcClient)
  300.     If m_lControlLines = 1 Then
  301.         GetTrayIconRect.Left = rcClock.Left - (16 + TRAY_PADDING) * (TrayIcons.Count - lIdx + 1) - TRAY_PADDING \ 2
  302.         GetTrayIconRect.Top = rcClock.Top + (rcClock.Bottom - rcClock.Top - 16 - TRAY_PADDING) \ 2
  303.     Else
  304.         lIconsPerLine = (TrayWidth - SEP_WIDTH - 2 * BRD_WIDTH - TRAY_PADDING) \ (16 + TRAY_PADDING)
  305.         lIconRow = (lIdx - 1) \ lIconsPerLine
  306.         GetTrayIconRect.Left = rcClock.Left + (16 + TRAY_PADDING) * (lIdx - lIconRow * lIconsPerLine - 1) + TRAY_PADDING \ 2
  307.         GetTrayIconRect.Top = rcClock.Bottom + (16 + TRAY_PADDING) * lIconRow
  308.     End If
  309.     GetTrayIconRect.Right = GetTrayIconRect.Left + 16 + TRAY_PADDING - 1
  310.     GetTrayIconRect.Bottom = GetTrayIconRect.Top + 16 + TRAY_PADDING - 1
  311. End Function
  312.  
  313. Private Function GetButtonHeight() As Long
  314.     On Error Resume Next
  315.     GetButtonHeight = CalcHeight(Font)
  316.     If GetButtonHeight < 19 Then
  317.         GetButtonHeight = 19
  318.     End If
  319.     GetButtonHeight = GetButtonHeight + 2 * BRD_WIDTH
  320. End Function
  321.  
  322. Private Function GetLineHeight() As Long
  323.     On Error Resume Next
  324.     GetLineHeight = GetButtonHeight() + BRD_WIDTH
  325. End Function
  326.  
  327. Private Function GetControlHeight() As Long
  328.     GetControlHeight = GetLineHeight() * m_lControlLines + BRD_WIDTH
  329. End Function
  330.  
  331. Private Function GetMaxControlLines() As Long
  332.     Dim rcClient        As RECT
  333.     
  334.     On Error Resume Next
  335.     GetClientRect GetParent(UserControl.hWnd), rcClient
  336.     GetMaxControlLines = (rcClient.Bottom - rcClient.Top) \ 2 \ GetLineHeight()
  337. End Function
  338.  
  339. Private Sub DrawSeparator(ByVal hdc As Long, rc As RECT)
  340.     Dim hDarkPen        As Long
  341.     Dim hLightPen       As Long
  342.     Dim hPrevPen        As Long
  343.     
  344.     On Error Resume Next
  345.     hDarkPen = CreatePen(0, 1, TranslateColor(vb3DShadow))
  346.     hLightPen = CreatePen(0, 1, TranslateColor(vb3DHighlight))
  347.     InflateRect rc, 0, -1
  348.     ExtTextOut hdc, 0, 0, ETO_OPAQUE, rc, "", 0, 0
  349.     InflateRect rc, 0, -2
  350.     '--- dark
  351.     hPrevPen = SelectObject(hdc, hDarkPen)
  352.     MoveToEx hdc, rc.Left + BRD_WIDTH, rc.Top, ByVal 0
  353.     LineTo hdc, rc.Left + BRD_WIDTH, rc.Bottom
  354.     MoveToEx hdc, rc.Left + BRD_WIDTH + 6, rc.Top + BRD_WIDTH, ByVal 0
  355.     LineTo hdc, rc.Left + BRD_WIDTH + 6, rc.Bottom - BRD_WIDTH
  356.     LineTo hdc, rc.Left + BRD_WIDTH + 4, rc.Bottom - BRD_WIDTH
  357.     '--- light
  358.     SelectObject hdc, hLightPen
  359.     MoveToEx hdc, rc.Left + BRD_WIDTH + 1, rc.Top, ByVal 0
  360.     LineTo hdc, rc.Left + BRD_WIDTH + 1, rc.Bottom
  361.     MoveToEx hdc, rc.Left + BRD_WIDTH + 5, rc.Top + BRD_WIDTH, ByVal 0
  362.     LineTo hdc, rc.Left + BRD_WIDTH + 4, rc.Top + BRD_WIDTH
  363.     LineTo hdc, rc.Left + BRD_WIDTH + 4, rc.Bottom - BRD_WIDTH - 1
  364.     '--- cleanup
  365.     SelectObject hdc, hPrevPen
  366.     DeleteObject hDarkPen
  367.     DeleteObject hLightPen
  368. End Sub
  369.  
  370. Private Sub DrawPicture( _
  371.         ByVal hdc As Long, _
  372.         oPic As StdPicture, _
  373.         ByVal X As Long, _
  374.         ByVal Y As Long, _
  375.         ByVal cxWidth As Long, _
  376.         ByVal cyHeight As Long)
  377.     Dim hMemDC          As Long
  378.     Dim hPrevBmp        As Long
  379.     Dim rc              As RECT
  380.     Dim hEmf            As Long
  381.     
  382.     On Error Resume Next
  383.     Select Case oPic.Type
  384.     Case vbPicTypeIcon
  385.         DrawIconEx hdc, X, Y, oPic.Handle, cxWidth, cyHeight, 0, 0, DI_NORMAL
  386.     Case vbPicTypeBitmap
  387.         hMemDC = CreateCompatibleDC(hdc)
  388.         hPrevBmp = SelectObject(hMemDC, oPic.Handle)
  389.         StretchBlt hdc, X, Y, cxWidth, cyHeight, hMemDC, 0, 0, oPic.Width / SNG_HIMETRIC, oPic.Height / SNG_HIMETRIC, SRCCOPY
  390.         SelectObject hMemDC, hPrevBmp
  391.         DeleteDC hMemDC
  392.     Case vbPicTypeEMetafile, vbPicTypeMetafile
  393.         rc.Left = X: rc.Top = Y
  394.         rc.Right = X + cxWidth: rc.Bottom = Y + cyHeight
  395.         If oPic.Type = vbPicTypeMetafile Then
  396.             hMemDC = CreateEnhMetaFileLong(hdc, vbNullString, 0, vbNullString)
  397.             PlayMetaFile hMemDC, oPic.Handle
  398.             hEmf = CloseEnhMetaFile(hMemDC)
  399.         Else
  400.             hEmf = oPic.Handle
  401.         End If
  402.         PlayEnhMetaFile hdc, hEmf, rc
  403.         If oPic.Type = vbPicTypeMetafile Then
  404.             DeleteEnhMetaFile hEmf
  405.         End If
  406.     End Select
  407. End Sub
  408.  
  409. Private Sub DrawControl()
  410.     Dim rcClient        As RECT
  411.     Dim rcButton        As RECT
  412.     Dim rcTray          As RECT
  413.     Dim hRgn            As Long
  414.     Dim hRgnButton      As Long
  415.     Dim lI              As Long
  416.     Dim lPrevBkColor    As Long
  417.     Dim sText           As String
  418.     Dim oTextMetric     As TEXTMETRIC
  419.     Dim lX              As Long
  420.     Dim lY              As Long
  421.     Dim oPic            As StdPicture
  422.     Dim hWinDC          As Long
  423.     Dim hdc             As Long
  424.     Dim hBmp            As Long
  425.     Dim hPrevBmp        As Long
  426.     Dim hFont           As Long
  427.     Dim hBoldFont       As Long
  428.     Dim hPrevFont       As Long
  429.     
  430.     
  431.     On Error Resume Next
  432.     '--- if anything to paint
  433.     '--- prepare
  434.     GetClientRect hWnd, rcClient
  435.     hWinDC = GetDC(hWnd)
  436. If BufferDraw Then
  437.     hdc = CreateCompatibleDC(hWinDC)
  438.     hBmp = CreateCompatibleBitmap(hWinDC, UpdateRect.Right - UpdateRect.Left, UpdateRect.Bottom - UpdateRect.Top)
  439.     hPrevBmp = SelectObject(hdc, hBmp)
  440.     lPrevBkColor = SetBkColor(hdc, TranslateColor(vbButtonFace))
  441.     ExtTextOut hdc, 0, 0, ETO_OPAQUE, rcClient, "", 0, 0
  442.     SetViewportOrgEx hdc, -UpdateRect.Left, -UpdateRect.Top, ByVal 0
  443. Else
  444.     hdc = hWinDC
  445.     lPrevBkColor = SetBkColor(hdc, TranslateColor(vbButtonFace))
  446. End If
  447.     hFont = CreateLogFont(hdc, Font)
  448.     Font.Bold = True
  449.     hBoldFont = CreateLogFont(hdc, Font)
  450.     Font.Bold = False
  451.     hPrevFont = SelectObject(hdc, hFont)
  452.     hRgn = CreateRectRgnIndirect(rcClient)
  453.     SetBkMode hdc, TRANSPARENT
  454.     GetTextMetrics hdc, oTextMetric
  455.     lX = Loword(GetDialogBaseUnits) / 4 + 1
  456.     SetStretchBltMode hdc, STRETCH_HALFTONE
  457.     
  458.     '--- calc button properties
  459.     m_lButtonWidth = (rcClient.Right - rcClient.Left - TrayWidth - GetStartMenuRect(rcClient).Right - SEP_WIDTH) \ ((Tasks.Count + m_lControlLines - 1) \ m_lControlLines)
  460.     If m_lButtonWidth > MAX_BUTTON_WIDTH Then
  461.         m_lButtonWidth = MAX_BUTTON_WIDTH
  462.     End If
  463.     m_lButtonsPerLine = (rcClient.Right - rcClient.Left - TrayWidth - GetStartMenuRect(rcClient).Right - SEP_WIDTH) \ m_lButtonWidth
  464.     
  465.     '--- start button
  466.     rcButton = GetStartMenuRect(rcClient)
  467.     If IsIntersectRect(rcButton, UpdateRect) Then
  468.         DrawFrameControl hdc, rcButton, DFC_BUTTON, IIf(m_lActive = 0, DFCS_BUTTONPUSH Or DFCS_PUSHED Or DFCS_CHECKED, DFCS_BUTTONPUSH)
  469.         hRgnButton = CreateRectRgnIndirect(rcButton)
  470.         CombineRgn hRgn, hRgn, hRgnButton, RGN_DIFF
  471.         DeleteObject hRgnButton
  472.         InflateRect rcButton, -BRD_WIDTH, -BRD_WIDTH
  473.         If 0 = m_lActive Then
  474.             OffsetRect rcButton, 1, 1
  475.             rcButton.Right = rcButton.Right - 1
  476.         End If
  477.         Set oPic = StartMenuIcon
  478.         If Not oPic Is Nothing Then
  479.             DrawPicture hdc, oPic, rcButton.Left, rcButton.Top + (rcButton.Bottom - rcButton.Top - 16) \ 2, 16, 16
  480.             rcButton.Left = rcButton.Left + 17
  481.         End If
  482.         sText = StartMenuCaption
  483.         lY = (rcButton.Bottom + rcButton.Top - oTextMetric.tmHeight) \ 2
  484.         SelectObject hdc, hBoldFont
  485.         SetTextAlign hdc, TA_LEFT
  486.         ExtTextOut hdc, rcButton.Left + lX, lY, ETO_CLIPPED, rcButton, sText, Len(sText), 0
  487.         SelectObject hdc, hFont
  488.         rcButton.Right = rcButton.Right + BRD_WIDTH
  489.     End If
  490.     
  491.     '--- taskbar
  492.     '--- separator
  493.     rcButton.Left = rcButton.Right
  494.     rcButton.Top = rcClient.Top
  495.     rcButton.Right = rcButton.Left + SEP_WIDTH
  496.     rcButton.Bottom = rcClient.Bottom
  497.     DrawSeparator hdc, rcButton
  498.     hRgnButton = CreateRectRgnIndirect(rcButton)
  499.     CombineRgn hRgn, hRgn, hRgnButton, RGN_DIFF
  500.     DeleteObject hRgnButton
  501.     '--- buttons
  502.     For lI = 1 To Tasks.Count
  503.         rcButton = GetButtonRect(rcClient, lI)
  504.         If IsIntersectRect(rcButton, UpdateRect) Then
  505.             DrawFrameControl hdc, rcButton, DFC_BUTTON, DFCS_BUTTONPUSH Or _
  506.                 Switch(lI = m_lActive, DFCS_PUSHED Or DFCS_CHECKED, _
  507.                     lI = m_lPressed, DFCS_PUSHED)
  508.             hRgnButton = CreateRectRgnIndirect(rcButton)
  509.             CombineRgn hRgn, hRgn, hRgnButton, RGN_DIFF
  510.             DeleteObject hRgnButton
  511.             InflateRect rcButton, -BRD_WIDTH, -BRD_WIDTH
  512.             If lI = m_lActive Then
  513.                 OffsetRect rcButton, 0, 1
  514.                 SelectObject hdc, hBoldFont
  515.             End If
  516.             Set oPic = Nothing
  517.             Set oPic = m_cTasks(lI).Icon
  518.             If Not oPic Is Nothing Then
  519.                 DrawPicture hdc, oPic, rcButton.Left, rcButton.Top + (rcButton.Bottom - rcButton.Top - 16) \ 2, 16, 16
  520.                 rcButton.Left = rcButton.Left + 17
  521.             End If
  522.             sText = ""
  523.             sText = m_cTasks(lI).Caption
  524.             PathCompactPath hdc, sText, rcButton.Right - rcButton.Left - lX - 1
  525.             If InStr(sText, Chr(0)) > 0 Then
  526.                 sText = Left(sText, InStr(sText, Chr(0)) - 1)
  527.             End If
  528.             lY = (rcButton.Bottom + rcButton.Top - oTextMetric.tmHeight) \ 2
  529.             SetTextAlign hdc, TA_LEFT
  530.             ExtTextOut hdc, rcButton.Left + lX, lY, ETO_CLIPPED, rcButton, sText, Len(sText), 0
  531.             SelectObject hdc, hFont
  532.         End If
  533.     Next
  534.     '--- tray
  535.     rcTray = GetTrayRect(rcClient)
  536.     rcButton.Left = rcTray.Left - SEP_WIDTH
  537.     rcButton.Top = rcClient.Top
  538.     rcButton.Right = rcButton.Left + SEP_WIDTH
  539.     rcButton.Bottom = rcClient.Bottom
  540.     '--- separator
  541.     DrawSeparator hdc, rcButton
  542.     hRgnButton = CreateRectRgnIndirect(rcButton)
  543.     CombineRgn hRgn, hRgn, hRgnButton, RGN_DIFF
  544.     DeleteObject hRgnButton
  545.     If IsIntersectRect(rcTray, UpdateRect) Then
  546.         '--- edge
  547.         rcButton = rcTray
  548.         ExtTextOut hdc, 0, 0, ETO_OPAQUE, rcButton, "", 0, 0
  549.         DrawEdge hdc, rcButton, BDR_SUNKENOUTER, BF_RECT
  550.         hRgnButton = CreateRectRgnIndirect(rcButton)
  551.         CombineRgn hRgn, hRgn, hRgnButton, RGN_DIFF
  552.         DeleteObject hRgnButton
  553.         '--- clock
  554.         rcButton = GetClockRect(rcClient)
  555.         sText = Format(Now, STR_SHORTTIME)
  556.         lY = (rcButton.Bottom + rcButton.Top - oTextMetric.tmHeight) \ 2
  557.         SetTextAlign hdc, TA_CENTER
  558.         ExtTextOut hdc, (rcButton.Left + rcButton.Right) \ 2, lY, ETO_OPAQUE Or ETO_CLIPPED, rcButton, sText, Len(sText), 0
  559.         '--- tray icons
  560.         For lI = 1 To TrayIcons.Count
  561.             rcButton = GetTrayIconRect(rcClient, lI)
  562.             Set oPic = Nothing
  563.             Set oPic = m_cTrayIcons(lI).Icon
  564.             If Not oPic Is Nothing Then
  565.                 DrawPicture hdc, oPic, rcButton.Left + TRAY_PADDING \ 2, rcButton.Top + (rcButton.Bottom - rcButton.Top - 16) \ 2, 16, 16
  566.             End If
  567.         Next
  568.     End If
  569.     '--- background and outer edge
  570.     DrawEdge hdc, rcClient, BDR_RAISEDINNER, BF_RECT
  571. If BufferDraw Then
  572.     SetViewportOrgEx hdc, 0, 0, ByVal 0
  573.     '-- bit-blit
  574.     BitBlt hWinDC, UpdateRect.Left, UpdateRect.Top, UpdateRect.Right - UpdateRect.Left, UpdateRect.Bottom - UpdateRect.Top, hdc, 0, 0, SRCCOPY
  575. Else
  576.     SelectClipRgn hdc, hRgn
  577.     InflateRect rcClient, -1, -1
  578.     ExtTextOut hdc, 0, 0, ETO_OPAQUE, rcClient, "", 0, 0
  579.     InflateRect rcClient, 1, 1
  580. End If
  581.     '--- clean up
  582.     SetBkColor hdc, lPrevBkColor
  583.     SelectClipRgn hdc, 0
  584.     DeleteObject hRgn
  585.     SelectObject hdc, hPrevBmp
  586.     DeleteObject hBmp
  587.     SelectObject hdc, hPrevFont
  588.     DeleteObject hFont
  589.     DeleteObject hBoldFont
  590. If BufferDraw Then
  591.     DeleteDC hdc
  592. Else
  593.     ReleaseDC hWnd, hdc
  594. End If
  595.     ReleaseDC hWnd, hWinDC
  596. End Sub
  597.  
  598. '=========================================================================
  599. ' Control events
  600. '=========================================================================
  601.  
  602. Private Sub UserControl_Initialize()
  603.     On Error Resume Next
  604.     m_lActive = -1
  605.     m_lControlLines = 1
  606.     Set m_cTasks = New cTaskBarInfos
  607.     m_cTasks.hWnd = UserControl.hWnd
  608.     Set m_cTrayIcons = New cTaskBarInfos
  609.     m_cTrayIcons.hWnd = UserControl.hWnd
  610. End Sub
  611.  
  612. Private Sub UserControl_Terminate()
  613.     On Error Resume Next
  614.     PaintUnsubclass hWnd
  615. End Sub
  616.  
  617. Private Sub UserControl_KeyDown(KeyCode As Integer, Shift As Integer)
  618. '--- received upon WM_CANCELMODE
  619.     If PressedTask <> 0 Then
  620.         PressedTask = 0
  621.     End If
  622.     '--- stop sizing
  623.     m_bResizing = False
  624. End Sub
  625.  
  626. Private Sub UserControl_KeyUp(KeyCode As Integer, Shift As Integer)
  627. '--- received upon WM_PAINT
  628.     DrawControl
  629. End Sub
  630.  
  631. Private Sub UserControl_InitProperties()
  632.     On Error Resume Next
  633.     Set Font = Ambient.Font
  634.     StartMenuCaption = DEF_STARTMENUCAPTION
  635.     StartMenuTooltipText = DEF_STARTMENUTOOLTIPCAPTION
  636.     Set StartMenuIcon = DEF_STARTMENUICON
  637.     BufferDraw = DEF_BUFFERDRAW
  638.     PaintSubclass hWnd, IIf(Ambient.UserMode, 1000, 0)
  639. End Sub
  640.  
  641. Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
  642.     On Error Resume Next
  643.     With PropBag
  644.         Set Font = .ReadProperty("Font", DEF_FONT)
  645.         StartMenuCaption = .ReadProperty("StartMenuCaption", DEF_STARTMENUCAPTION)
  646.         StartMenuTooltipText = .ReadProperty("StartMenuTooltipText", DEF_STARTMENUTOOLTIPCAPTION)
  647.         Set StartMenuIcon = .ReadProperty("StartMenuIcon", DEF_STARTMENUICON)
  648.         BufferDraw = .ReadProperty("BufferDraw", DEF_BUFFERDRAW)
  649.     End With
  650.     PaintSubclass hWnd, IIf(Ambient.UserMode, 1000, 0)
  651. End Sub
  652.  
  653. Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
  654.     On Error Resume Next
  655.     With PropBag
  656.         .WriteProperty "Font", Font, DEF_FONT
  657.         .WriteProperty "StartMenuCaption", StartMenuCaption, DEF_STARTMENUCAPTION
  658.         .WriteProperty "StartMenuTooltipText", StartMenuTooltipText, DEF_STARTMENUTOOLTIPCAPTION
  659.         .WriteProperty "StartMenuIcon", StartMenuIcon, DEF_STARTMENUICON
  660.         .WriteProperty "BufferDraw", BufferDraw, DEF_BUFFERDRAW
  661.     End With
  662. End Sub
  663.  
  664. Private Sub UserControl_Resize()
  665.     On Error Resume Next
  666.     Height = ScaleY(GetControlHeight(), vbPixels)
  667.     imgCapture.Move 0, 0, ScaleWidth, ScaleHeight
  668.     Refresh
  669. End Sub
  670.  
  671. Private Sub imgCapture_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  672.     Dim pt              As POINTAPI
  673.     Dim rcClient        As RECT
  674.     Dim lI              As Long
  675.     Dim rc              As RECT
  676.     
  677.     On Error Resume Next
  678.     GetClientRect hWnd, rcClient
  679.     pt.X = ScaleX(X, vbTwips, vbPixels)
  680.     pt.Y = ScaleY(Y, vbTwips, vbPixels)
  681.     '--- check if sizing
  682.     If imgCapture.MousePointer = vbSizeNS And Button = vbLeftButton Then
  683.         m_bResizing = True
  684.         Exit Sub
  685.     End If
  686.     '--- ignore event if sizing
  687.     If m_bResizing Then
  688.         Exit Sub
  689.     End If
  690.     '--- hittest start menu
  691.     rc = GetStartMenuRect(rcClient)
  692.     If PtInRect(rc, pt) Then
  693.         RaiseEvent TaskMouseDown(0, Button, pt.X - rc.Left, pt.Y - rc.Top)
  694.         If Button = vbLeftButton Then
  695.             ActiveTask = 0
  696.             RaiseEvent StartMenu
  697.             ActiveTask = -1
  698.         End If
  699.         Exit Sub
  700.     End If
  701.     '--- hittest tasks
  702.     For lI = 1 To Tasks.Count
  703.         rc = GetButtonRect(rcClient, lI)
  704.         If PtInRect(rc, pt) Then
  705.             RaiseEvent TaskMouseDown(lI, Button, pt.X - rc.Left, pt.Y - rc.Top)
  706.             If Button = vbLeftButton Then
  707.                 PressedTask = lI
  708.             End If
  709.             Exit Sub
  710.         End If
  711.     Next
  712.     '--- hittest clock
  713.     rc = GetClockRect(rcClient)
  714.     If PtInRect(rc, pt) Then
  715.         RaiseEvent TrayMouseDown(0, Button, pt.X - rc.Left, pt.Y - rc.Top)
  716.         Exit Sub
  717.     End If
  718.     '--- hittest tray icons
  719.     For lI = 1 To TrayIcons.Count
  720.         rc = GetTrayIconRect(rcClient, lI)
  721.         If PtInRect(rc, pt) Then
  722.             RaiseEvent TrayMouseDown(lI, Button, pt.X - rc.Left, pt.Y - rc.Top)
  723.             Exit Sub
  724.         End If
  725.     Next
  726. End Sub
  727.  
  728. Private Sub imgCapture_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
  729.     Dim pt              As POINTAPI
  730.     Dim rcClient        As RECT
  731.     Dim lI              As Long
  732.     Dim rc              As RECT
  733.     Dim lControlLines   As Long
  734.     
  735.     On Error Resume Next
  736.     GetClientRect hWnd, rcClient
  737.     pt.X = ScaleX(X, vbTwips, vbPixels)
  738.     pt.Y = ScaleY(Y, vbTwips, vbPixels)
  739.     If m_bResizing Then
  740.         '--- figure out new control size
  741.         If Extender.Align = vbAlignBottom Then
  742.             lControlLines = m_lControlLines - Round(ScaleY(Y, vbTwips, vbPixels) / GetLineHeight())
  743.         Else
  744.             lControlLines = m_lControlLines + Round((ScaleY(Y, vbTwips, vbPixels) - rcClient.Bottom) / GetLineHeight())
  745.         End If
  746.         If lControlLines < 1 Then
  747.             lControlLines = 1
  748.         ElseIf lControlLines > GetMaxControlLines() Then
  749.             lControlLines = GetMaxControlLines()
  750.         End If
  751.         If lControlLines <> m_lControlLines Then
  752.             m_lControlLines = lControlLines
  753.             UserControl_Resize
  754.         End If
  755.         Exit Sub
  756.     End If
  757.     '--- change mouse pointer
  758.     If Extender.Align = vbAlignBottom Then
  759.         imgCapture.MousePointer = IIf(pt.Y >= 0 And pt.Y <= BRD_WIDTH, vbSizeNS, vbDefault)
  760.     Else
  761.         imgCapture.MousePointer = IIf(pt.Y >= rcClient.Bottom - BRD_WIDTH And pt.Y <= rcClient.Bottom, vbSizeNS, vbDefault)
  762.     End If
  763.     '--- if task pressed
  764.     If (Button And vbLeftButton) <> 0 And m_lPressed <> 0 Then
  765.         If m_lPressed > 0 Then
  766.             If Not PtInRect(GetButtonRect(rcClient, m_lPressed), pt) Then
  767.                 PressedTask = -PressedTask
  768.             End If
  769.         Else
  770.             If PtInRect(GetButtonRect(rcClient, -m_lPressed), pt) Then
  771.                 PressedTask = -PressedTask
  772.             End If
  773.         End If
  774.     End If
  775.     '--- hittest start menu
  776.     rc = GetStartMenuRect(rcClient)
  777.     If PtInRect(rc, pt) Then
  778.         If StartMenuTooltipText <> "" Then
  779.             imgCapture.TooltipText = StartMenuTooltipText
  780.         Else
  781.             imgCapture.TooltipText = StartMenuCaption
  782.         End If
  783.         Exit Sub
  784.     End If
  785.     '--- hittest tasks
  786.     For lI = 1 To Tasks.Count
  787.         rc = GetButtonRect(rcClient, lI)
  788.         If PtInRect(rc, pt) Then
  789.             If Tasks(lI).TooltipText <> "" Then
  790.                 imgCapture.TooltipText = Tasks(lI).TooltipText
  791.             Else
  792.                 imgCapture.TooltipText = Tasks(lI).Caption
  793.             End If
  794.             Exit Sub
  795.         End If
  796.     Next
  797.     '--- hittest tray icons
  798.     For lI = 1 To TrayIcons.Count
  799.         rc = GetTrayIconRect(rcClient, lI)
  800.         If PtInRect(rc, pt) Then
  801.             If TrayIcons(lI).TooltipText <> "" Then
  802.                 imgCapture.TooltipText = TrayIcons(lI).TooltipText
  803.             Else
  804.                 imgCapture.TooltipText = TrayIcons(lI).Caption
  805.             End If
  806.             Exit Sub
  807.         End If
  808.     Next
  809.     '--- hittest clock
  810.     rc = GetClockRect(rcClient)
  811.     If PtInRect(rc, pt) Then
  812.         imgCapture.TooltipText = Format(Date, STR_LONGDATE)
  813.         Exit Sub
  814.     End If
  815.     '--- no tooltip
  816.     imgCapture.TooltipText = ""
  817. End Sub
  818.  
  819. Private Sub imgCapture_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
  820.     Dim bCancel         As Boolean
  821.     Dim pt              As POINTAPI
  822.     Dim rcClient        As RECT
  823.     Dim rc              As RECT
  824.     Dim lI              As Long
  825.     
  826.     On Error Resume Next
  827.     GetClientRect hWnd, rcClient
  828.     pt.X = ScaleX(X, vbTwips, vbPixels)
  829.     pt.Y = ScaleY(Y, vbTwips, vbPixels)
  830.     '--- stop sizing if left button
  831.     If m_bResizing Then
  832.         If Button = vbLeftButton Then
  833.             m_bResizing = False
  834.         End If
  835.         Exit Sub
  836.     End If
  837.     '--- hittest start menu
  838.     rc = GetStartMenuRect(rcClient)
  839.     If PtInRect(rc, pt) Then
  840.         RaiseEvent TaskMouseUp(0, Button, pt.X - rc.Left, pt.Y - rc.Top)
  841.         Exit Sub
  842.     End If
  843.     '--- hittest tasks
  844.     For lI = 1 To Tasks.Count
  845.         rc = GetButtonRect(rcClient, lI)
  846.         If PtInRect(rc, pt) Then
  847.             RaiseEvent TaskMouseUp(lI, Button, pt.X - rc.Left, pt.Y - rc.Top)
  848.             If Button = vbLeftButton Then
  849.                 If m_lPressed <> 0 Then
  850.                     If m_lPressed > 0 Then
  851.                         RaiseEvent BeforeTaskSwitch(m_lPressed, bCancel)
  852.                         If Not bCancel Then
  853.                             ActiveTask = m_lPressed
  854.                         End If
  855.                     End If
  856.                     PressedTask = 0
  857.                 End If
  858.             End If
  859.             Exit Sub
  860.         End If
  861.     Next
  862.     '--- hittest clock
  863.     rc = GetClockRect(rcClient)
  864.     If PtInRect(rc, pt) Then
  865.         RaiseEvent TrayMouseUp(0, Button, pt.X - rc.Left, pt.Y - rc.Top)
  866.         Exit Sub
  867.     End If
  868.     '--- hittest tray icons
  869.     For lI = 1 To TrayIcons.Count
  870.         rc = GetTrayIconRect(rcClient, lI)
  871.         If PtInRect(rc, pt) Then
  872.             RaiseEvent TrayMouseUp(lI, Button, pt.X - rc.Left, pt.Y - rc.Top)
  873.         End If
  874.     Next
  875. End Sub
  876.  
  877.